package com.sdhs.analyze.service.monitor;

import com.sdhs.analyze.bean.DicNodeType;
import com.sdhs.analyze.bean.InfoNodeStatus;
import com.sdhs.analyze.bean.InfoNodeStatusTrace;
import com.sdhs.analyze.common.BizConstants;
import com.sdhs.analyze.dao.nodestatus.NodeStatusMapper;
import com.sdhs.analyze.dao.nodestatustrace.NodeStatusTraceMapper;
import com.sdhs.analyze.schedule.GantryMonitorTaskHandler;
import com.sdhs.analyze.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class NodeStatusService {

    private static Logger logger = LoggerFactory.getLogger(GantryMonitorTaskHandler.class);

    @Autowired
    private NodeStatusTraceMapper nodeStatusTraceMapper;

    @Autowired
    private NodeStatusMapper nodeStatusMapper;

    private static String nodeStatusSplit = ",";

    /**
     * 保存节点状态和状态跟踪信息
     *
     * @param orgId
     * @param newNodeStatusMap
     */
    @Transactional
    public void saveInfoNodeStatusAndTrace(String orgId, Map<String, InfoNodeStatus> newNodeStatusMap,
                                           Map<String, DicNodeType> nodeTypeMap) {

        try {
            Date now = new Date();

            /* 查询原节点状态 */
            List<InfoNodeStatus> oldNodeStatusList = getNodeStatusByGantryBackId(orgId);
            Map<String, InfoNodeStatus> oldNodeStatusMap = new HashMap<>();
            for (InfoNodeStatus infoNodeStatus : oldNodeStatusList) {
                String key = infoNodeStatus.getNodeId() + nodeStatusSplit + infoNodeStatus.getNodeType();
                oldNodeStatusMap.put(key, infoNodeStatus);
            }

            /* 查询原节点跟踪状态 */
            List<InfoNodeStatusTrace> oldNodeStatusTraceList = nodeStatusTraceMapper.selectNodeStatusTraceByGantryBackId(orgId);
            Map<String, InfoNodeStatusTrace> oldNodeStatusTraceMap = new HashMap<>();
            for (InfoNodeStatusTrace infoNodeStatusTrace : oldNodeStatusTraceList) {
                String key = infoNodeStatusTrace.getNodeId() + nodeStatusSplit + infoNodeStatusTrace.getNodeType();
                oldNodeStatusTraceMap.put(key, infoNodeStatusTrace);
            }

            /* 开始处理 */
            for (InfoNodeStatus newNodeStatus : newNodeStatusMap.values()) {

                InfoNodeStatus oldNodeStatus = oldNodeStatusMap.get(newNodeStatus.getKey());

                InfoNodeStatusTrace oldNodeStatusTrace = oldNodeStatusTraceMap.get(newNodeStatus.getKey());

                InfoNodeStatusTrace tmpNodeStatusTrace = oldNodeStatusTrace;

                /* 状态发生变化 */
                if (oldNodeStatus == null || oldNodeStatus.getStatus() != newNodeStatus.getStatus()) {
                    /* 更新状态 */
                    nodeStatusMapper.insertOrUpdateNodeStatus(newNodeStatus);

                    if (oldNodeStatusTrace != null) {
                        /* 状态发生变化，状态跟踪信息移至历史表 */
                        oldNodeStatusTrace.setEndTime(newNodeStatus.getStatusCheckTime());
                        // 插入到状态表
                        Integer datePoor = DateUtils.getDatePoor2(newNodeStatus.getStatusCheckTime(), oldNodeStatusTrace.getStartTime());
                        /* 只保存大于等于0的记录 */
                        if (datePoor >= 0) {
                            oldNodeStatusTrace.setDuration(datePoor);
                            nodeStatusTraceMapper.insertNodeStatusTraceHistory(oldNodeStatusTrace);
                        }
                        nodeStatusTraceMapper.deleteNodeStatusTrace(oldNodeStatusTrace);
                    }

                    /* 状态仍大于0的，继续跟踪 */
                    if (newNodeStatus.getStatus() > 0) {
                        InfoNodeStatusTrace newNodeStatusTrace = new InfoNodeStatusTrace();
                        newNodeStatusTrace.setNodeId(newNodeStatus.getNodeId());
                        newNodeStatusTrace.setNodeType(newNodeStatus.getNodeType());
                        newNodeStatusTrace.setOrgId(newNodeStatus.getOrgId());
                        newNodeStatusTrace.setOrgType(newNodeStatus.getOrgType());
                        newNodeStatusTrace.setStartTime(newNodeStatus.getStatusCheckTime());
                        newNodeStatusTrace.setEndTime(new Date(0));
                        newNodeStatusTrace.setExcLevel(newNodeStatus.getStatus());
                        newNodeStatusTrace.setWarnFlag(0);
                        newNodeStatusTrace.setDescription(newNodeStatus.getDescription());
                        newNodeStatusTrace.setNodeName(newNodeStatus.getNodeName());
                        tmpNodeStatusTrace = newNodeStatusTrace;
                        nodeStatusTraceMapper.insertNodeStatusTrace(newNodeStatusTrace);
                    }
                }

                /* 更新状态检查时间 */
                if (newNodeStatus.getNodeType().equals(BizConstants.NODE_TYPE_ETC_GANTRY_SYSTEM)) {

                    nodeStatusMapper.updateStatusCheckTime(newNodeStatus);
                }

                /* 处于异常状态的，判断是否达到告警条件 */
                if (newNodeStatus.getStatus() > 0) {
                    /* 未告警的 */
                    if (tmpNodeStatusTrace.getWarnFlag() == null ||
                            tmpNodeStatusTrace.getWarnFlag() == 0) {

                        Integer datePoor = DateUtils.getDatePoor2(now, tmpNodeStatusTrace.getStartTime());

                        DicNodeType nodeType = nodeTypeMap.get(tmpNodeStatusTrace.getNodeType());

                        /* 达到告警级别且达到告警间隔 */
                        if (tmpNodeStatusTrace.getExcLevel() >= nodeType.getAlarmLevel() && datePoor >= nodeType.getAlarmDelay()) {
                            tmpNodeStatusTrace.setWarnFlag(1);
                            tmpNodeStatusTrace.setWarnTime(now);
                            nodeStatusTraceMapper.updateWarnFlag(tmpNodeStatusTrace);
                        }
                    }
                }
            }
            /* 将状态信息保存Redis */
        } catch (Exception ex) {

            logger.error(ex.getMessage(), ex);

            throw ex;
        }
    }

    /**
     * 组织节点状态信息
     *
     * @param dicNodeType
     * @param nodeId
     * @param nodeName
     * @param status
     * @param parentNodeId
     * @param description
     * @return
     */
    public InfoNodeStatus makeNodeStatus(
            DicNodeType dicNodeType,
            String nodeId, String nodeName,
            String orgId, Integer status,
            String parentNodeId, String description, Date checkTime) {
        InfoNodeStatus infoNodeStatus = new InfoNodeStatus();
        infoNodeStatus.setKey(nodeId + "," + dicNodeType.getNodeType());
        infoNodeStatus.setNodeId(nodeId);
        infoNodeStatus.setNodeType(dicNodeType.getNodeType());
        infoNodeStatus.setOrgId(orgId);
        infoNodeStatus.setOrgType(Integer.parseInt(dicNodeType.getOrgType()));
        infoNodeStatus.setNodeName(nodeName);
        infoNodeStatus.setStatus(status);
        infoNodeStatus.setParentNodeId(parentNodeId);
        infoNodeStatus.setParentNodeType(dicNodeType.getParentNodeType());
        infoNodeStatus.setDescription(description);
        infoNodeStatus.setDisplayLevel(dicNodeType.getDisplayLevel());
        infoNodeStatus.setStatusCheckTime(checkTime);
        infoNodeStatus.setStatusChangeTime(new Date());
        return infoNodeStatus;
    }

    /**
     * 使用门架后台获取节点状态
     *
     * @param orgId
     * @return
     */
    public List<InfoNodeStatus> getNodeStatusByGantryBackId(String orgId) {
        return nodeStatusMapper.getNodeStatusByGantryBackId(orgId);
    }
}
